package service

import (
	"context"
	"database/sql"
	"encoding/json"
	"fmt"
	"fx_swift_forex/api"
	"fx_swift_forex/internal/model"
	"fx_swift_forex/pkg/code"
	"fx_swift_forex/pkg/global"
	"fx_swift_forex/pkg/internalerrors"
	"fx_swift_forex/pkg/logger"
	"fx_swift_forex/pkg/utils"
	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/google/uuid"
	"strconv"
	"strings"
)

type IComplySrv interface {
	CreateCustomer(ctx context.Context, req *api.ComplyOnboardingReq) (*api.CustomerOnboardingRes, error)
	PostCompanyCustomer(ctx context.Context, req *ComplyCompanyOnboardingReq) error
	PostPersonCustomer(ctx context.Context, req *model.ComplyPersonOnboardingReq) error
	CreateCustomerTemp(ctx context.Context, req *api.CustomerTempReq) error
	GetCustomerTemp(ctx context.Context) (*api.CustomerTempRes, error)
	GetCustomerMessage(ctx context.Context) ([]*api.CustomerMessageRes, error)
	GetPaymentInfo(ctx context.Context) ([]*api.PaymentRes, error)
	GetPaymentPurposeInfo(ctx context.Context) ([]*api.PaymentPurposeRes, error)
	GetIncomeSourceInfo(ctx context.Context) ([]*api.IncomeSourceRes, error)
	CheckEmail(ctx context.Context, email string) (bool, error)
}

type complySrv struct {
}

func NewComplySrv() IComplySrv {
	return &complySrv{}
}

// 校验企业邮箱是否唯一
func (c complySrv) CheckEmail(ctx context.Context, email string) (bool, error) {
	var (
		err error
		num int
	)
	//num, err = global.GFDB.Ctx(ctx).Model("forex_customer_tmp").Where("INSTR(req_json, ?)", "\""+email+"\"").Count()
	num, err = global.GFDB.Ctx(ctx).Model("forex_contacts").Where("email_address", email).Count()
	if err != nil {
		return false, internalerrors.New(code.ErrUnknown, "查询数据有误")
	}
	if num >= 1 {
		return true, err
	}
	return false, nil
}

// 获取收入来源
func (c complySrv) GetIncomeSourceInfo(ctx context.Context) ([]*api.IncomeSourceRes, error) {
	var (
		err             error
		incomeSourceObj []*api.IncomeSourceRes
	)

	if err = global.GFDB.Schema("forex").Ctx(ctx).Model("forex_income_source_base").Scan(&incomeSourceObj); err != nil {
		logger.SugarLogger.Error(err)
		return nil, internalerrors.New(code.ErrUnknown, "查询数据报错")
	}
	if incomeSourceObj == nil {
		return []*api.IncomeSourceRes{}, nil
	}
	return incomeSourceObj, err
}

// 获取账户收付款用途
func (c complySrv) GetPaymentPurposeInfo(ctx context.Context) ([]*api.PaymentPurposeRes, error) {
	var (
		err               error
		paymentPurposeObj []*api.PaymentPurposeRes
	)

	if err = global.GFDB.Schema("forex").Ctx(ctx).Model("forex_payment_purpose_base").Scan(&paymentPurposeObj); err != nil {
		logger.SugarLogger.Error(err)
		return nil, internalerrors.New(code.ErrUnknown, "查询数据报错")
	}
	if paymentPurposeObj == nil {
		return []*api.PaymentPurposeRes{}, nil
	}
	return paymentPurposeObj, err
}

// 获取收/付款总额
func (c complySrv) GetPaymentInfo(ctx context.Context) ([]*api.PaymentRes, error) {
	var (
		err        error
		paymentObj []*api.PaymentRes
	)

	if err = global.GFDB.Schema("forex").Ctx(ctx).Model("forex_payment_base").Scan(&paymentObj); err != nil {
		logger.SugarLogger.Error(err)
		return nil, internalerrors.New(code.ErrUnknown, "查询数据报错")
	}
	if paymentObj == nil {
		return []*api.PaymentRes{}, nil
	}
	return paymentObj, err
}

// 获取KYC客户状态信息
func (c complySrv) GetCustomerMessage(ctx context.Context) ([]*api.CustomerMessageRes, error) {
	var (
		err         error
		account     string
		accountType string
		customerObj []*api.CustomerMessageRes
	)

	account = ctx.Value("Account").(string)
	accountType = ctx.Value("UserType").(string)
	if accountType == "00" {
		if err = global.GFDB.Ctx(ctx).Model("forex_onboarding_customer").
			Where("account=?", account).
			Scan(&customerObj); err != nil {
			return nil, internalerrors.New(code.ErrUnknown, err.Error())
		}
	} else {
		if err = global.GFDB.Ctx(ctx).Model("forex_onboarding_customer foc").
			LeftJoin("forex_company fc", "foc.customer_id=fc.customer_id").
			Fields("foc.customer_id,foc.customer_status,foc.message,fc.legal_name").
			Where("account=?", account).
			Scan(&customerObj); err != nil {
			return nil, internalerrors.New(code.ErrUnknown, err.Error())
		}
	}

	if len(customerObj) == 0 {
		return []*api.CustomerMessageRes{}, nil
	}

	result := make([]*api.CustomerMessageRes, 0)
	for _, value := range customerObj {
		result = append(result, &api.CustomerMessageRes{
			CustomerId:     value.CustomerId,
			CustomerStatus: value.CustomerStatus,
			Message:        value.Message,
			LegalName:      value.LegalName,
			//ScreeningResult: screen,
			//OverallLevel:    overLevel,
			//OverallValue:    overValue,
		})
	}
	return result, err
}

// 获取KYC临时资料
func (c complySrv) GetCustomerTemp(ctx context.Context) (*api.CustomerTempRes, error) {
	var (
		err        error
		account    string
		customerId string
		reqJsonObj *api.CustomerTempRes
	)

	account = ctx.Value("Account").(string)
	customerId, err = GetRedisCustomerId(ctx)

	if err = global.GFDB.Ctx(ctx).Model("forex_customer_tmp").Where("account=? and customer_id=?", account, customerId).
		Scan(&reqJsonObj); err != nil {
		return nil, internalerrors.New(code.ErrUnknown, err.Error())
	}
	if reqJsonObj == nil {
		return &api.CustomerTempRes{}, nil
	}

	return &api.CustomerTempRes{
		Account:    reqJsonObj.Account,
		ReqJson:    reqJsonObj.ReqJson,
		CustomerId: reqJsonObj.CustomerId,
	}, err
}

// KYC认证资料临时保存
func (c complySrv) CreateCustomerTemp(ctx context.Context, req *api.CustomerTempReq) error {
	var (
		err        error
		reqJsonObj []*model.ForexCustomerTmp
		result     sql.Result
		rowsNums   int64
	)
	account := req.Account
	if req.Account == "" {
		account = ctx.Value("Account").(string)
	}
	accountType := req.AccountType
	if accountType == "" {
		accountType = ctx.Value("UserType").(string)
	}

	mod := global.GFDB.Ctx(ctx).Model("forex_customer_tmp")
	if req.CustomerId == "" {
		mod.Where("customer_id=?", req.CustomerId)
	}
	if account != "" {
		mod.Where("account=?", account)
	}
	err = mod.Scan(&reqJsonObj)
	if err != nil {
		logger.SugarLogger.Error(err)
		return internalerrors.New(code.ErrUnknown, "数据查询异常")
	}
	if len(reqJsonObj) == 0 {
		result, err = global.GFDB.Insert(ctx, "forex_customer_tmp", &model.ForexCustomerTmp{
			Account:    account,
			ReqJson:    req.ReqJson,
			CustomerId: req.CustomerId,
		})

		if err != nil {
			logger.SugarLogger.Error(err)
			return internalerrors.New(code.ErrUnknown, "kyc认证资料写入异常")
		}
		rowsNums, err = result.RowsAffected()
		if err != nil || rowsNums == 0 {
			logger.SugarLogger.Error(err)
			return internalerrors.New(code.ErrUnknown, "kyc认证资料写入异常")
		}
	} else {
		if accountType == "00" {
			if req.ReqJson != "" {
				result, err = global.GFDB.Ctx(ctx).Model("forex_customer_tmp").
					Data(g.Map{"req_json": req.ReqJson}).Where("account=?", account).Update()
			} else {
				result, err = global.GFDB.Ctx(ctx).Model("forex_customer_tmp").
					Data(g.Map{"customer_id": req.CustomerId}).Where("account=?", account).Update()
			}
		} else {
			if req.ReqJson != "" {
				result, err = global.GFDB.Ctx(ctx).Model("forex_customer_tmp").
					Data(g.Map{"req_json": req.ReqJson}).Where("account=? and customer_id=?", account, req.CustomerId).Update()
			} else {
				num, err := global.GFDB.Ctx(ctx).Model("forex_customer_tmp").Where("account=? and customer_id=?", account, req.CustomerId).Count()
				if err != nil {
					return internalerrors.New(code.ErrUnknown, "校验临时资料查询有误")
				}
				if num > 0 {
					result, err = global.GFDB.Ctx(ctx).Model("forex_customer_tmp").
						Data(g.Map{"customer_id": req.CustomerId}).Where("account=? and customer_id=?", account, req.CustomerId).Update()
				} else {
					result, err = global.GFDB.Ctx(ctx).Model("forex_customer_tmp").
						Data(g.Map{"customer_id": req.CustomerId}).Where("account=? and customer_id=''", account).Update()
				}

			}

		}
		if err != nil {
			logger.SugarLogger.Error(err)
			return internalerrors.New(code.ErrUnknown, "kyc认证资料更新异常")
		}
		rowsNums, err = result.RowsAffected()
		if err != nil || rowsNums == 0 {
			logger.SugarLogger.Error(err)
			return internalerrors.New(code.ErrUnknown, "kyc认证资料更新异常")
		}
	}

	return err
}

// 创建个人用户kyc资料
func (c complySrv) CreateCustomer(ctx context.Context, req *api.ComplyOnboardingReq) (*api.CustomerOnboardingRes, error) {
	var (
		err            error
		customerResult []*model.ForexOnboardingCustomer
		customerId     string
		//redisResult    *gvar.Var
		//accessToken    string
	)

	if utils.IsEmptyStruct(req.Customer.Person) && utils.IsEmptyStruct(req.Customer.Company) {
		return nil, internalerrors.New(code.ErrUnknown, "客户信息不能为空")
	}
	if !utils.IsEmptyStruct(req.Customer.Person) && req.Customer.Person.FirstName == "" {
		return nil, internalerrors.New(code.ErrUnknown, "FirstName不能为空")
	}
	if !utils.IsEmptyStruct(req.Customer.Person) && req.Customer.Person.LastName == "" {
		return nil, internalerrors.New(code.ErrUnknown, "LastName不能为空")
	}
	if !utils.IsEmptyStruct(req.Customer.Person) && len(req.Customer.Person.ContactInformation.PhoneNumber) == 0 {
		return nil, internalerrors.New(code.ErrUnknown, "电话号码不能为空")
	}
	if !utils.IsEmptyStruct(req.Customer.Person) && utils.IsEmptyStruct(req.Customer.Person.DateOfBirth) {
		return nil, internalerrors.New(code.ErrUnknown, "出生日期不能为空")
	}
	if !utils.IsEmptyStruct(req.Customer.Company) && req.Customer.Company.LegalName == "" {
		return nil, internalerrors.New(code.ErrUnknown, "LegalName不能为空")
	}
	if !utils.IsEmptyStruct(req.Customer.Person) && req.Customer.Person.Address != nil && req.Customer.Person.Address[0].AddressLine1 == "" {
		return nil, internalerrors.New(code.ErrUnknown, "AddressLine1不能为空")
	}
	if !utils.IsEmptyStruct(req.Customer.Company) && req.Customer.Company.Addresses != nil && req.Customer.Company.Addresses[0].AddressLine1 == "" {
		return nil, internalerrors.New(code.ErrUnknown, "AddressLine1不能为空")
	}
	if !utils.IsEmptyStruct(req.Customer.Person) && req.Customer.Person.PersonalIdentification != nil && req.Customer.Person.PersonalIdentification[0].IssuingCountry == "" {
		return nil, internalerrors.New(code.ErrUnknown, "IssuingCountry不能为空")
	}
	if !utils.IsEmptyStruct(req.Customer.Company) && req.Customer.Company.Addresses != nil && req.Customer.Company.Addresses[0].Country == "" {
		return nil, internalerrors.New(code.ErrUnknown, "Country不能为空")
	}
	if !utils.IsEmptyStruct(req.Customer.Person) && req.Customer.Person.Address != nil && req.Customer.Person.Address[0].TownName == "" {
		return nil, internalerrors.New(code.ErrUnknown, "TownName不能为空")
	}
	if !utils.IsEmptyStruct(req.Customer.Company) && req.Customer.Company.Addresses != nil && req.Customer.Company.Addresses[0].TownName == "" {
		return nil, internalerrors.New(code.ErrUnknown, "TownName不能为空")
	}
	if !utils.IsEmptyStruct(req.Customer.Person) && req.Customer.Person.Address != nil && req.Customer.Person.Address[0].CountrySubdivision == "" {
		return nil, internalerrors.New(code.ErrUnknown, "CountrySubdivision不能为空")
	}
	if !utils.IsEmptyStruct(req.Customer.Company) && req.Customer.Company.Addresses != nil && req.Customer.Company.Addresses[0].CountrySubdivision == "" {
		return nil, internalerrors.New(code.ErrUnknown, "CountrySubdivision不能为空")
	}
	if !utils.IsEmptyStruct(req.Customer.Person) && req.Customer.Person.PersonalIdentification != nil {
		if req.Customer.Person.PersonalIdentification[0].Type == "" || req.Customer.Person.PersonalIdentification[0].DocumentIdentifier == "" {
			return nil, internalerrors.New(code.ErrUnknown, "身份类型/身份号码不能为空")
		}
	}
	if !utils.IsEmptyStruct(req.Customer.Company) && req.Customer.Company.RegistrationAuthorityIdentification == "" {
		return nil, internalerrors.New(code.ErrUnknown, "公司注册号不能为空")
	}

	account := ctx.Value("Account").(string)
	accountType := ctx.Value("UserType").(string)
	uuidStr := uuid.New()
	customerId = fmt.Sprintf("%x", uuidStr[:12])

	mod := global.GFDB.Ctx(ctx).Model("forex_onboarding_customer")
	if req.Customer.CustomerId != "" {
		mod.Where("customer_id=?", req.Customer.CustomerId)
	}
	if account != "" {
		mod.Where("account=?", account)
	}
	err = mod.Scan(&customerResult)
	if err != nil {
		logger.SugarLogger.Error(err)
		return nil, internalerrors.New(code.ErrUnknown, "数据查询异常")
	}
	if len(customerResult) != 0 {
		if accountType == "00" {
			//个人kyc
			if customerResult[0].CustomerStatus == "COMPLETED" {
				return nil, internalerrors.New(code.ErrUnknown, "已有入职调查记录")
			} else {
				customerId = req.Customer.CustomerId
			}
		} else {
			//企业kyc
			if req.Customer.CustomerId != "" {
				customerId = req.Customer.CustomerId
			}
		}
	}

	db := g.DB()
	err = db.Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		//person入库
		if !utils.IsEmptyStruct(req.Customer.Person) {
			personList := []*model.ForexPerson{}
			personObj := &model.ForexPerson{}
			personObj.CustomerId = customerId
			personObj.FirstName = req.Customer.Person.FirstName
			personObj.LastName = req.Customer.Person.LastName
			personObj.MiddleName = req.Customer.Person.MiddleName
			personObj.Gender = req.Customer.Person.Gender
			if req.Customer.Person.Nationality != nil {
				personObj.Nationality = strings.Join(req.Customer.Person.Nationality, ";")
			}
			personObj.Title = req.Customer.Person.Title
			if req.Customer.Person.Address != nil {
				addStr, _ := json.Marshal(req.Customer.Person.Address)
				personObj.Address = string(addStr)
			}
			if !utils.IsEmptyStruct(req.Customer.Person.DateOfBirth) {
				dateOfBirth, _ := json.Marshal(req.Customer.Person.DateOfBirth)
				personObj.DateOfBirth = string(dateOfBirth)
			}
			if !utils.IsEmptyStruct(req.Customer.Person.ContactInformation) {
				contactInfo, _ := json.Marshal(req.Customer.Person.ContactInformation)
				personObj.ContactInformation = string(contactInfo)
			}
			personObj.CountryOfBirth = req.Customer.Person.CountryOfBirth
			if len(req.Customer.Person.PersonalIdentification) != 0 {
				personIdentification, _ := json.Marshal(req.Customer.Person.PersonalIdentification)
				personObj.PersonalIdentification = string(personIdentification)
			}
			if req.Customer.Person.Profession != nil {
				personObj.Profession = strings.Join(req.Customer.Person.Profession, ";")
			}
			if len(req.Customer.Person.ResidentialInformation) != 0 {
				residentialInfo, _ := json.Marshal(req.Customer.Person.ResidentialInformation)
				personObj.ResidentialInformation = string(residentialInfo)
			}
			personObj.SalaryCurrency = req.Customer.Person.SalaryCurrency
			if !utils.IsEmptyStruct(req.Customer.Person.SalaryRange) {
				salaryRange, _ := json.Marshal(req.Customer.Person.SalaryRange)
				personObj.SalaryRange = string(salaryRange)
			}
			personObj.SourceOfWealth = req.Customer.Person.SourceOfWealth
			personList = append(personList, personObj)

			//先删除
			result, err := global.GFDB.Model("forex_person").Where("customer_id", customerId).Delete()
			if err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "person资料删除失败")
			}
			//后插入
			result, err = tx.Model("forex_person").Data(personList).Insert()

			if err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "person资料插入失败")
			}
			rowsNums, err := result.RowsAffected()
			if err != nil || rowsNums == 0 {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "person资料插入失败")
			}
		}

		//company入库
		if !utils.IsEmptyStruct(req.Customer.Company) {
			compayList := []*model.ForexCompany{}
			companyObj := &model.ForexCompany{}
			companyObj.CustomerId = customerId
			companyObj.CompanyStatus = req.Customer.Company.CompanyStatus
			if len(req.Customer.Company.Aliases) != 0 {
				companyObj.Aliases = strings.Join(req.Customer.Company.Aliases, ";")
			}
			companyObj.CompanyType = req.Customer.Company.CompanyType
			companyObj.LegalName = req.Customer.Company.LegalName
			companyObj.PlaceOfRegistration = req.Customer.Company.PlaceOfRegistration
			companyObj.RegistrationAuthorityIdentification = req.Customer.Company.RegistrationAuthorityIdentification
			if !utils.IsEmptyStruct(req.Customer.Company.IncorporationDate) {
				inDate, _ := json.Marshal(req.Customer.Company.IncorporationDate)
				companyObj.IncorporationDate = string(inDate)
			}
			if len(req.Customer.Company.Addresses) != 0 {
				address, _ := json.Marshal(req.Customer.Company.Addresses)
				companyObj.Addresses = string(address)
			}
			compayList = append(compayList, companyObj)
			//先删除
			result, err := global.GFDB.Model("forex_company").Where("customer_id", customerId).Delete()
			if err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "company资料删除失败")
			}
			//后插入
			result, err = tx.Model("forex_company").Data(compayList).Insert()

			if err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "company资料插入失败")
			}
			rowsNums, err := result.RowsAffected()
			if err != nil || rowsNums == 0 {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "company资料插入失败")
			}
		}
		//customer主表入库
		if !utils.IsEmptyStruct(req.Customer) {
			customerList := []*model.ForexOnboardingCustomer{}
			customerObj := &model.ForexOnboardingCustomer{}
			customerObj.CustomerId = customerId
			customerObj.Account = account
			customerObj.ExternalIdentifier = customerId
			var customerStatus = "APPROVAL"
			var message = ""
			if len(customerResult) != 0 && req.Customer.CustomerId != "" {
				message = customerResult[0].Message
				customerObj.Configuration = customerResult[0].Configuration
				customerObj.ExternalIdentifier = customerResult[0].ExternalIdentifier
				customerObj.CustomerIdentifier = customerResult[0].CustomerIdentifier
				customerObj.WorkflowInstanceIdentifier = customerResult[0].WorkflowInstanceIdentifier
				customerObj.ScreeningResult = customerResult[0].ScreeningResult
				customerObj.OverallValue = customerResult[0].OverallValue
				customerObj.OverallLevel = customerResult[0].OverallLevel
			}
			customerObj.CustomerStatus = customerStatus
			customerObj.Message = message
			customerList = append(customerList, customerObj)

			//先删除
			result, err := global.GFDB.Model("forex_onboarding_customer").Where("customer_id", customerId).Delete()
			if err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "customer资料删除失败")
			}
			//后插入
			result, err = tx.Model("forex_onboarding_customer").Data(customerList).Insert()

			if err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "customer资料插入失败")
			}
			rowsNums, err := result.RowsAffected()
			if err != nil || rowsNums == 0 {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "customer资料插入失败")
			}
		}

		//product入库
		//if len(req.Product) != 0 {
		//	productList := []*model.ForexProduct{}
		//	for _, value := range req.Product {
		//		productObj := &model.ForexProduct{}
		//		productObj.CustomerId = customerId
		//		productObj.ProductName = value.ProductName
		//		productObj.ProductStatus = value.ProductStatus
		//		productObj.Currency = value.Currency
		//		productObj.MonthlyPaymentValue = value.MonthlyPaymentValue
		//		productObj.MonthlyReceivedValue = value.MonthlyReceivedValue
		//		productObj.MonthlyTransactionNumber = value.MonthlyTransactionNumber
		//		productObj.Purpose = value.Purpose
		//		if !utils.IsEmptyStruct(value.ProductDetails) {
		//			details, _ := json.Marshal(value.ProductDetails)
		//			productObj.ProductDetails = string(details)
		//		}
		//		if !utils.IsEmptyStruct(value.OnboardingChannel) {
		//			channel, _ := json.Marshal(value.OnboardingChannel)
		//			productObj.OnboardingChannel = string(channel)
		//		}
		//		productList = append(productList, productObj)
		//	}
		//	//先删除
		//	result, err := global.GFDB.Model("forex_product").Where("customer_id", customerId).Delete()
		//	if err != nil {
		//		logger.SugarLogger.Error(err)
		//		return internalerrors.New(code.ErrUnknown, "product资料删除失败")
		//	}
		//	//后插入
		//	result, err = tx.Model("forex_product").Data(productList).Insert()
		//
		//	if err != nil {
		//		logger.SugarLogger.Error(err)
		//		return internalerrors.New(code.ErrUnknown, "product资料插入失败")
		//	}
		//	rowsNums, err := result.RowsAffected()
		//	if err != nil || rowsNums == 0 {
		//		logger.SugarLogger.Error(err)
		//		return internalerrors.New(code.ErrUnknown, "product资料插入失败")
		//	}
		//}
		return nil
	})
	if err != nil {
		logger.SugarLogger.Error("KYC后台入库执行出错", err)
		return nil, internalerrors.New(code.ErrUnknown, "KYC后台入库失败")
	} else {
		logger.SugarLogger.Info("KYC后台入库执行成功")
	}
	//对kyc资料进行临时备份，以便入库失败进行补数据
	customerTmp := &api.CustomerTempReq{
		CustomerId: customerId,
	}
	err = c.CreateCustomerTemp(ctx, customerTmp)
	if err != nil {
		logger.SugarLogger.Error("kyc资料备份失败", err)
	}
	//设置customerId到redis
	if err = g.Redis().SetEX(ctx, account+"_customerId", customerId, 174600); err != nil {
		logger.SugarLogger.Errorf("创建kyc记录时，customerId写redis失败")
	}
	return &api.CustomerOnboardingRes{
		Account:     account,
		AccountType: accountType,
		CustomerId:  customerId,
	}, nil
}

type ComplyCompanyOnboardingReq struct {
	Customer *api.Customer `json:"customer"`
	//Product     []*api.ProductList `json:"product"`
	Account     string `json:"account"`
	AccountType string `json:"account_type"`
}

// 提交企业kyc资料
func (c complySrv) PostCompanyCustomer(ctx context.Context, req *ComplyCompanyOnboardingReq) error {
	var (
		err                        error
		customerResult             []*model.ForexOnboardingCustomer
		customerId                 string
		workflowInstanceIdentifier string
	)

	if !utils.IsEmptyStruct(req.Customer.Company) && req.Customer.Company.LegalName == "" {
		return internalerrors.New(code.ErrUnknown, "LegalName不能为空")
	}
	account := req.Account
	//accountType := req.AccountType
	customerId = req.Customer.CustomerId
	if err = global.GFDB.Schema("forex").Model("forex_onboarding_customer").
		Where("account=? and customer_id=?", account, customerId).Scan(&customerResult); err != nil {
		logger.SugarLogger.Error(err)
		return internalerrors.New(code.ErrUnknown, err.Error())
	}
	//if len(customerResult) != 0 {
	//	if accountType == "00" {
	//		//个人kyc
	//		if customerResult[0].CustomerStatus == "COMPLETED" {
	//			return internalerrors.New(code.ErrUnknown, "已有入职调查记录")
	//		} else {
	//			customerId = req.Customer.CustomerId
	//		}
	//	} else {
	//		//企业kyc
	//		if req.Customer.CustomerId != "" {
	//			customerId = req.Customer.CustomerId
	//		}
	//	}
	//}
	req.Customer.ExternalIdentifier.Id = customerId

	//TODO 先调用天眼查基本信息接口校验该企业是否大陆企业

	//TODO 如果是大陆企业则提交到天眼查立案信息接口校验是否有未结案案件

	//如果是境外企业则提交客户记录到comply进行入职调查
	reqJson, err := json.Marshal(req)
	fmt.Println("企业kyc入参打印：", string(reqJson))
	workflowInstanceIdentifier, err = DoPostCompanyComply(ctx, req)
	g.Dump("kyc响应参数worklowInstanceIdentifier：", workflowInstanceIdentifier)
	if err != nil {
		logger.SugarLogger.Error(err)
		return internalerrors.New(code.ErrUnknown, err.Error())
	}
	//获取公司法人或董事信息
	legalPerson := &api.LegalPerson{}
	if err = global.GFDB.Ctx(ctx).Model("forex_customer_tmp").Fields("JSON_UNQUOTE(JSON_EXTRACT(req_json,\"$.internal.step2.legalPerson\")) as legal_person").Where("account=? and customer_id=?", account, customerId).
		Scan(&legalPerson); err != nil {
		return internalerrors.New(code.ErrUnknown, err.Error())
	}

	//CC银行企业开户
	accountsReq := &api.AccountReq{
		AccountName:                "FX01" + utils.GenerateRandomNumber(8),
		LegalEntityType:            "company",
		YourReference:              customerId,
		Street:                     req.Customer.Company.Addresses[0].AddressLine1,
		Country:                    req.Customer.Company.Addresses[0].Country,
		StateOrProvince:            req.Customer.Company.Addresses[0].CountrySubdivision,
		City:                       req.Customer.Company.Addresses[0].TownName,
		PostalCode:                 req.Customer.Company.Addresses[0].PostCode,
		IdentificationType:         "incorporation_number",
		IdentificationValue:        req.Customer.Company.RegistrationAuthorityIdentification,
		Status:                     "enabled",
		OnlineTrading:              "false",
		PhoneTrading:               "false",
		TermsAndConditionsAccepted: "true",
	}
	accountId, err := CreateAccounts(ctx, accountsReq)
	if err != nil || accountId == "" {
		return internalerrors.New(code.ErrUnknown, err.Error())
	}

	////添加账户联系人
	contactsReq := &api.ContactsReq{
		AccountId:     accountId,
		FirstName:     legalPerson.LegalPerson.FirstName,
		LastName:      legalPerson.LegalPerson.LastName,
		EmailAddress:  legalPerson.LegalPerson.ContactInformation.EmailAddress[0],
		PhoneNumber:   legalPerson.LegalPerson.ContactInformation.PhoneNumber[0],
		YourReference: customerId,
		Status:        "enabled",
		DateOfBirth:   strconv.Itoa(legalPerson.LegalPerson.DateOfBirth.Year) + "-" + utils.PadZero(legalPerson.LegalPerson.DateOfBirth.Month) + "-" + utils.PadZero(legalPerson.LegalPerson.DateOfBirth.Day),
	}
	err = CreateContacts(ctx, contactsReq)
	if err != nil {
		return internalerrors.New(code.ErrUnknown, err.Error())
	}

	//入库操作
	db := g.DB()
	err = db.Schema("forex").Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		//company入库
		if !utils.IsEmptyStruct(req.Customer.Company) {
			compayList := []*model.ForexCompany{}
			companyObj := &model.ForexCompany{}
			companyObj.CustomerId = customerId
			companyObj.CompanyStatus = req.Customer.Company.CompanyStatus
			if len(req.Customer.Company.Aliases) != 0 {
				companyObj.Aliases = strings.Join(req.Customer.Company.Aliases, ";")
			}
			companyObj.CompanyType = req.Customer.Company.CompanyType
			companyObj.LegalName = req.Customer.Company.LegalName
			companyObj.PlaceOfRegistration = req.Customer.Company.PlaceOfRegistration
			companyObj.RegistrationAuthorityIdentification = req.Customer.Company.RegistrationAuthorityIdentification
			if !utils.IsEmptyStruct(req.Customer.Company.IncorporationDate) {
				inDate, _ := json.Marshal(req.Customer.Company.IncorporationDate)
				companyObj.IncorporationDate = string(inDate)
			}
			if len(req.Customer.Company.Addresses) != 0 {
				address, _ := json.Marshal(req.Customer.Company.Addresses)
				companyObj.Addresses = string(address)
			}
			compayList = append(compayList, companyObj)
			//先删除
			result, err := global.GFDB.Schema("forex").Model("forex_company").Where("customer_id", customerId).Delete()
			if err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "company资料删除失败")
			}
			//后插入
			result, err = tx.Model("forex_company").Data(compayList).Insert()

			if err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "company资料插入失败")
			}
			rowsNums, err := result.RowsAffected()
			if err != nil || rowsNums == 0 {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "company资料插入失败")
			}
		}
		//customer主表入库
		if req.Customer != nil {
			customerList := []*model.ForexOnboardingCustomer{}
			customerObj := &model.ForexOnboardingCustomer{}
			customerObj.CustomerId = customerId
			customerObj.Account = account
			customerObj.ExternalIdentifier = req.Customer.ExternalIdentifier.Id
			customerObj.WorkflowInstanceIdentifier = workflowInstanceIdentifier
			//var customerStatus = "APPROVAL"
			//if customerResult != nil {
			customerObj.CustomerStatus = customerResult[0].CustomerStatus
			customerObj.Configuration = ""
			customerObj.CustomerIdentifier = ""
			customerObj.ScreeningResult = ""
			customerObj.OverallValue = ""
			customerObj.OverallLevel = ""
			//}
			customerList = append(customerList, customerObj)

			//先删除
			result, err := global.GFDB.Schema("forex").Model("forex_onboarding_customer").Where("customer_id", customerId).Delete()
			if err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "customer资料删除失败")
			}
			//后插入
			result, err = tx.Model("forex_onboarding_customer").Data(customerList).Insert()

			if err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "customer资料插入失败")
			}
			rowsNums, err := result.RowsAffected()
			if err != nil || rowsNums == 0 {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "customer资料插入失败")
			}
		}

		//product入库
		//if len(req.Product) != 0 {
		//	productList := []*model.ForexProduct{}
		//	for _, value := range req.Product {
		//		productObj := &model.ForexProduct{}
		//		productObj.CustomerId = customerId
		//		productObj.ProductName = value.ProductName
		//		productObj.ProductStatus = value.ProductStatus
		//		productObj.Currency = value.Currency
		//		productObj.MonthlyPaymentValue = value.MonthlyPaymentValue
		//		productObj.MonthlyReceivedValue = value.MonthlyReceivedValue
		//		productObj.MonthlyTransactionNumber = value.MonthlyTransactionNumber
		//		productObj.Purpose = value.Purpose
		//		if !utils.IsEmptyStruct(value.ProductDetails) {
		//			details, _ := json.Marshal(value.ProductDetails)
		//			productObj.ProductDetails = string(details)
		//		}
		//		if !utils.IsEmptyStruct(value.OnboardingChannel) {
		//			channel, _ := json.Marshal(value.OnboardingChannel)
		//			productObj.OnboardingChannel = string(channel)
		//		}
		//		productList = append(productList, productObj)
		//	}
		//	//先删除
		//	result, err := global.GFDB.Schema("forex").Model("forex_product").Where("customer_id", customerId).Delete()
		//	if err != nil {
		//		logger.SugarLogger.Error(err)
		//		return internalerrors.New(code.ErrUnknown, "product资料删除失败")
		//	}
		//	//后插入
		//	result, err = tx.Model("forex_product").Data(productList).Insert()
		//
		//	if err != nil {
		//		logger.SugarLogger.Error(err)
		//		return internalerrors.New(code.ErrUnknown, "product资料插入失败")
		//	}
		//	rowsNums, err := result.RowsAffected()
		//	if err != nil || rowsNums == 0 {
		//		logger.SugarLogger.Error(err)
		//		return internalerrors.New(code.ErrUnknown, "product资料插入失败")
		//	}
		//}
		return nil
	})
	if err != nil {
		logger.SugarLogger.Error("KYC事务执行出错", err)
		return internalerrors.New(code.ErrUnknown, "KYC资料录入失败")
	} else {
		logger.SugarLogger.Info("KYC事务执行成功")
	}
	//对kyc资料进行临时备份，以便入库失败进行补数据
	//customerTmp := &api.CustomerTempReq{
	//	Account:     account,
	//	AccountType: accountType,
	//	CustomerId:  customerId,
	//}
	//err = c.CreateCustomerTemp(ctx, customerTmp)
	//if err != nil {
	//	logger.SugarLogger.Error("kyc资料备份失败", err)
	//}

	return nil
}

// 提交个人kyc资料
func (c complySrv) PostPersonCustomer(ctx context.Context, req *model.ComplyPersonOnboardingReq) error {
	var (
		err                       error
		customerResult            []*model.ForexOnboardingCustomer
		customerId                string
		worklowInstanceIdentifier string
	)

	if req.Customer.Person.PersonalIdentification[0].DocumentIdentifier == "" {
		return internalerrors.New(code.ErrUnknown, "DocumentIdentifier证件号不能为空")
	}
	if req.Customer.Person.LastName == "" {
		return internalerrors.New(code.ErrUnknown, "LastName不能为空")
	}
	account := req.Account
	//accountType := req.AccountType
	customerId = req.Customer.CustomerId
	if err = global.GFDB.Schema("forex").Model("forex_onboarding_customer").
		Where("account=? and customer_id=?", account, customerId).Scan(&customerResult); err != nil {
		logger.SugarLogger.Error(err)
		return internalerrors.New(code.ErrUnknown, err.Error())
	}
	//if len(customerResult) != 0 {
	//	if accountType == "00" {
	//		//个人kyc
	//		if customerResult[0].CustomerStatus == "COMPLETED" {
	//			return internalerrors.New(code.ErrUnknown, "已有入职调查记录")
	//		} else {
	//			customerId = req.Customer.CustomerId
	//		}
	//	} else {
	//		//企业kyc
	//		if req.Customer.CustomerId != "" {
	//			customerId = req.Customer.CustomerId
	//		}
	//	}
	//}
	req.Customer.ExternalIdentifier.Id = customerId

	//提交客户记录到comply进行入职调查
	reqJson, err := json.Marshal(req)
	fmt.Println("个人kyc入参打印：", string(reqJson))
	worklowInstanceIdentifier, err = DoPostPersonComply(ctx, req)
	g.Dump("kyc响应参数worklowInstanceIdentifier：", worklowInstanceIdentifier)
	if err != nil {
		logger.SugarLogger.Error(err)
		return internalerrors.New(code.ErrUnknown, err.Error())
	}
	//CC银行个人开户
	accountsReq := &api.AccountReq{
		AccountName:                "FX00" + utils.GenerateRandomNumber(8),
		LegalEntityType:            "individual",
		YourReference:              customerId,
		Street:                     req.Customer.Person.Address[0].AddressLine1,
		Country:                    req.Customer.Person.ResidentialInformation[0].CountryOfResidence,
		StateOrProvince:            req.Customer.Person.Address[0].CountrySubdivision,
		City:                       req.Customer.Person.Address[0].TownName,
		PostalCode:                 req.Customer.Person.Address[0].PostCode,
		IdentificationType:         "national_id",
		IdentificationValue:        req.Customer.Person.PersonalIdentification[0].DocumentIdentifier,
		Status:                     "enabled",
		OnlineTrading:              "false",
		PhoneTrading:               "false",
		TermsAndConditionsAccepted: "true",
	}
	accountId, err := CreateAccounts(ctx, accountsReq)
	if err != nil || accountId == "" {
		return internalerrors.New(code.ErrUnknown, err.Error())
	}
	//添加账户联系人
	contactsReq := &api.ContactsReq{
		AccountId:     accountId,
		FirstName:     req.Customer.Person.FirstName,
		LastName:      req.Customer.Person.LastName,
		EmailAddress:  ctx.Value("Email").(string),
		PhoneNumber:   req.Customer.Person.ContactInformation.PhoneNumber[0],
		YourReference: customerId,
		Status:        "enabled",
		DateOfBirth:   strconv.Itoa(int(req.Customer.Person.DateOfBirth.Year)) + "-" + utils.PadZero(int(req.Customer.Person.DateOfBirth.Month)) + "-" + utils.PadZero(int(req.Customer.Person.DateOfBirth.Day)),
	}
	err = CreateContacts(ctx, contactsReq)
	if err != nil {
		return internalerrors.New(code.ErrUnknown, err.Error())
	}

	//入库操作
	db := g.DB()
	err = db.Schema("forex").Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {
		//person入库
		if !utils.IsEmptyStruct(req.Customer.Person) {
			personList := []*model.ForexPerson{}
			personObj := &model.ForexPerson{}
			personObj.CustomerId = customerId
			personObj.FirstName = req.Customer.Person.FirstName
			personObj.LastName = req.Customer.Person.LastName
			personObj.MiddleName = req.Customer.Person.MiddleName
			personObj.Gender = req.Customer.Person.Gender
			if req.Customer.Person.Nationality != nil {
				personObj.Nationality = strings.Join(req.Customer.Person.Nationality, ";")
			}
			personObj.Title = req.Customer.Person.Title
			if len(req.Customer.Person.Address) != 0 {
				addStr, _ := json.Marshal(req.Customer.Person.Address)
				personObj.Address = string(addStr)
			}
			if !utils.IsEmptyStruct(req.Customer.Person.DateOfBirth) {
				dateOfBirth, _ := json.Marshal(req.Customer.Person.DateOfBirth)
				personObj.DateOfBirth = string(dateOfBirth)
			}
			if !utils.IsEmptyStruct(req.Customer.Person.ContactInformation) {
				contactInfo, _ := json.Marshal(req.Customer.Person.ContactInformation)
				personObj.ContactInformation = string(contactInfo)
			}
			personObj.CountryOfBirth = req.Customer.Person.CountryOfBirth
			if len(req.Customer.Person.PersonalIdentification) != 0 {
				personIdentification, _ := json.Marshal(req.Customer.Person.PersonalIdentification)
				personObj.PersonalIdentification = string(personIdentification)
			}
			if req.Customer.Person.Profession != nil {
				personObj.Profession = strings.Join(req.Customer.Person.Profession, ";")
			}
			if len(req.Customer.Person.ResidentialInformation) != 0 {
				residentialInfo, _ := json.Marshal(req.Customer.Person.ResidentialInformation)
				personObj.ResidentialInformation = string(residentialInfo)
			}
			personObj.SalaryCurrency = req.Customer.Person.SalaryCurrency
			if !utils.IsEmptyStruct(req.Customer.Person.SalaryRange) {
				salaryRange, _ := json.Marshal(req.Customer.Person.SalaryRange)
				personObj.SalaryRange = string(salaryRange)
			}
			personObj.SourceOfWealth = req.Customer.Person.SourceOfWealth
			personList = append(personList, personObj)

			//先删除
			result, err := global.GFDB.Schema("forex").Model("forex_person").Where("customer_id", customerId).Delete()
			if err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "person资料删除失败")
			}
			//后插入
			result, err = tx.Model("forex_person").Data(personList).Insert()

			if err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "person资料插入失败")
			}
			rowsNums, err := result.RowsAffected()
			if err != nil || rowsNums == 0 {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "person资料插入失败")
			}
		}
		//customer主表入库
		if !utils.IsEmptyStruct(req.Customer) {
			customerList := []*model.ForexOnboardingCustomer{}
			customerObj := &model.ForexOnboardingCustomer{}
			customerObj.CustomerId = customerId
			customerObj.Account = account
			customerObj.ExternalIdentifier = req.Customer.ExternalIdentifier.Id
			customerObj.WorkflowInstanceIdentifier = worklowInstanceIdentifier
			//var customerStatus = "APPROVAL"
			//if customerResult != nil {
			customerObj.CustomerStatus = customerResult[0].CustomerStatus
			customerObj.Configuration = ""
			customerObj.CustomerIdentifier = ""
			customerObj.ScreeningResult = ""
			customerObj.OverallValue = ""
			customerObj.OverallLevel = ""
			//}
			customerList = append(customerList, customerObj)

			//先删除
			result, err := global.GFDB.Schema("forex").Model("forex_onboarding_customer").Where("customer_id", customerId).Delete()
			if err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "customer资料删除失败")
			}
			//后插入
			result, err = tx.Model("forex_onboarding_customer").Data(customerList).Insert()

			if err != nil {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "customer资料插入失败")
			}
			rowsNums, err := result.RowsAffected()
			if err != nil || rowsNums == 0 {
				logger.SugarLogger.Error(err)
				return internalerrors.New(code.ErrUnknown, "customer资料插入失败")
			}
		}

		//product入库
		//if len(req.Product) != 0 {
		//	productList := []*model.ForexProduct{}
		//	for _, value := range req.Product {
		//		productObj := &model.ForexProduct{}
		//		productObj.CustomerId = customerId
		//		productObj.ProductName = value.ProductName
		//		productObj.ProductStatus = value.ProductStatus
		//		productObj.Currency = value.Currency
		//		productObj.MonthlyPaymentValue = value.MonthlyPaymentValue
		//		productObj.MonthlyReceivedValue = value.MonthlyReceivedValue
		//		productObj.MonthlyTransactionNumber = value.MonthlyTransactionNumber
		//		productObj.Purpose = value.Purpose
		//		if !utils.IsEmptyStruct(value.ProductDetails) {
		//			details, _ := json.Marshal(value.ProductDetails)
		//			productObj.ProductDetails = string(details)
		//		}
		//		if !utils.IsEmptyStruct(value.OnboardingChannel) {
		//			channel, _ := json.Marshal(value.OnboardingChannel)
		//			productObj.OnboardingChannel = string(channel)
		//		}
		//		productList = append(productList, productObj)
		//	}
		//	//先删除
		//	result, err := global.GFDB.Schema("forex").Model("forex_product").Where("customer_id", customerId).Delete()
		//	if err != nil {
		//		logger.SugarLogger.Error(err)
		//		return internalerrors.New(code.ErrUnknown, "product资料删除失败")
		//	}
		//	//后插入
		//	result, err = tx.Model("forex_product").Data(productList).Insert()
		//
		//	if err != nil {
		//		logger.SugarLogger.Error(err)
		//		return internalerrors.New(code.ErrUnknown, "product资料插入失败")
		//	}
		//	rowsNums, err := result.RowsAffected()
		//	if err != nil || rowsNums == 0 {
		//		logger.SugarLogger.Error(err)
		//		return internalerrors.New(code.ErrUnknown, "product资料插入失败")
		//	}
		//}
		return nil
	})
	if err != nil {
		logger.SugarLogger.Error("KYC事务执行出错", err)
		return internalerrors.New(code.ErrUnknown, "KYC资料录入失败")
	} else {
		logger.SugarLogger.Info("KYC事务执行成功")
	}
	//对kyc资料进行临时备份，以便入库失败进行补数据
	//customerTmp := &api.CustomerTempReq{
	//	Account:     account,
	//	AccountType: accountType,
	//	CustomerId:  customerId,
	//}
	//err = c.CreateCustomerTemp(ctx, customerTmp)
	//if err != nil {
	//	logger.SugarLogger.Error("kyc资料备份失败", err)
	//}

	return nil
}
